﻿ using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Casamiel.Common;
using Casamiel.Domain.Entity;

using Enyim.Caching;
using Microsoft.Extensions.Options;
using Smooth.IoC.UnitOfWork.Interfaces;
using Casamiel.Domain;

namespace Casamiel.Application
{
    /// <summary>
    /// Member service.
    /// </summary>
	public sealed  class MemberService : IMemberService
	{
		private readonly IMemberAccessTokenRepository _tokenRepository;
		private readonly IMemberRepository _member;
		private readonly IMemcachedClient _memcachedClient;
		private readonly string _memcachedPre = "";
		private readonly bool _cacheEnable = false;
		private readonly int _cacheSeconds = 7200;
		
        public MemberService(IOptionsSnapshot<CasamielSettings> snapshot, IMemberAccessTokenRepository tokenRepository,
			IMemberRepository member, IMemcachedClient memcachedClient)
		{
            if (snapshot == null)
            {
                throw new ArgumentNullException(nameof(snapshot)); 
            }
			_cacheEnable = snapshot.Value.CacheEnable;
			_memcachedPre = snapshot.Value.MemcachedPre;
			_tokenRepository = tokenRepository;
			_member = member;
			_memcachedClient = memcachedClient;
		}
		public async Task AddAsync<TSession>(MemberAccessToken token) where TSession:class,ISession
		{
			await _tokenRepository.SaveAsync<TSession>(token).ConfigureAwait(false);
		}

		public async Task AddAsync<TSession>(Member member) where TSession : class, ISession
		{
			 await _member.SaveAsync<TSession>(member).ConfigureAwait(false);
		}

		public async Task<MemberAccessToken>FindAsync<TSession>(string mobile, int loginType,bool iscache=true) where TSession : class, ISession
		{
			 
			if (_cacheEnable && iscache) {
				var _cacheKey = _memcachedPre + Constant.TOKEN_PREFIX + mobile + "_" + loginType;
				var entity = await _memcachedClient.GetValueAsync<MemberAccessToken>(_cacheKey);
				if (entity == null) {
					entity = await _tokenRepository.FindAsync<TSession>(mobile, loginType).ConfigureAwait(false);
					if (entity != null) {
						await _memcachedClient.AddAsync(_cacheKey, entity, _cacheSeconds).ConfigureAwait(false);
					}
				}
				return entity;
			}
			return await _tokenRepository.FindAsync<TSession>(mobile, loginType).ConfigureAwait(false);
			 
		}

	 

		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="TSession"></typeparam>
		/// <param name="mobile"></param>
		/// <param name="IsCache"></param>
		/// <returns></returns>
		public async Task<Member> FindAsync<TSession>(string mobile,bool IsCache=false) where TSession : class, ISession
		{
			if (_cacheEnable && IsCache) {
				var _cacheKey = _memcachedPre + Constant.MEMBERINFO + mobile;
				var entity = await _memcachedClient.GetValueAsync<Member>(_cacheKey).ConfigureAwait(false);
				if (entity == null) {
					entity = await _member.FindAsync<TSession>(mobile).ConfigureAwait(false);
					if (entity != null) {
						await _memcachedClient.AddAsync(_cacheKey, entity, _cacheSeconds).ConfigureAwait(false);
					}
				}
				return entity;
			}
			return await _member.FindAsync<TSession>(mobile).ConfigureAwait(false);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="TSession"></typeparam>
		/// <param name="pageIndex"></param>
		/// <param name="pageSize"></param>
		/// <returns></returns>
		public async Task<PagingResult<Member>> GetListAsync<TSession>(int pageIndex,int pageSize) where TSession : class, ISession
		{
			var list = await _member.GetListAsync<ICasaMielSession>(pageIndex, pageSize, "", "Id").ConfigureAwait(false);
			return list;
		}
		//public bool Update<TSession>(MemberAccessToken token) where TSession : class, ISession
		//{
		//	return _tokenRepository.Update<TSession>(token);
		//}
		public async Task<bool> UpdateAsync<TSession>(MemberAccessToken token) where TSession : class, ISession
		{
            var success= await _tokenRepository.UpdateAsync<TSession>(token).ConfigureAwait(false);
			if (_cacheEnable && success) {
				var _cacheKey = _memcachedPre + Constant.TOKEN_PREFIX + token.Mobile + "_" + token.Login_Type;
				await _memcachedClient.RemoveAsync(_cacheKey).ConfigureAwait(false);
			}
			return success;
		}
		
        /// <summary>
        /// Updates the async.
        /// </summary>
        /// <returns>The async.</returns>
        /// <param name="member">Member.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
	    public async Task<bool> UpdateAsync<TSession>(Member member) where TSession : class, ISession
		{
			return await	_member.UpdateAsync<TSession>(member).ConfigureAwait(false);
		}


		public async Task<bool> UpdateLastLoginDateAsync<TSession>(long ID,DateTime LastLoginDate) where TSession : class, ISession
		{
			return await _member.UpdateLastLoginDateAsync<ICasaMielSession>(ID, LastLoginDate).ConfigureAwait(false);
		}
	}
}
